package com.lmx.persistence.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.lmx.common.constants.CommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.repoDomain.tmodel.Conf;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerDrug;
import com.lmx.repoDomain.tmodel.CustomerDrugProject;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectExe;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectItem;
import com.lmx.repoDomain.tmodel.CustomerDrugRecord;
import com.lmx.repoDomain.tmodel.CustomerNursingPlan;
import com.lmx.repoDomain.tmodel.CustomerNursingPlanModel;
import com.lmx.repoDomain.tmodel.CustomerServiceBill;
import com.lmx.repoDomain.tmodel.CustomerServiceItem;
import com.lmx.repoDomain.tmodel.DicttypeTenant;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.EvaluateResult;
import com.lmx.repoDomain.tmodel.NurseGroup;
import com.lmx.repoDomain.tmodel.NurseMerch;
import com.lmx.repoDomain.tmodel.NursingLevel;
import com.lmx.repoDomain.tmodel.NursingPlanDetail;
import com.lmx.repoDomain.tmodel.NursingPlanExecute;
import com.lmx.repoDomain.tmodel.NursingPlanServiceItem;
import com.lmx.repoDomain.tmodel.NursingProject;
import com.lmx.repoDomain.tmodel.NursingProjectServiceItem;
import com.lmx.repoDomain.tmodel.Role;
import com.lmx.repoDomain.tmodel.ServiceFinishLevel;
import com.lmx.repoDomain.tmodel.ServiceMerch;
import com.lmx.repoDomain.tmodel.ServicesExe;
import com.lmx.repoDomain.tmodel.SpecService;
import com.lmx.repoDomain.tmodel.WorkTimeSetting;
import com.lmx.repoDomain.tmodel.business.User;

/**
 *
 *
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class NursingService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	private Properties properties = PropertiesFileUtil.getApplicationProperties();

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected UserService userService;

	@Autowired
	protected CommonService commonService;

	@Autowired
	protected WeiXinService weiXinService;

	public void addPlanItem(NursingPlanServiceItem planItem) {
		dslJpaService.setEntityClass(NursingPlanServiceItem.class);
		dslJpaService.create(planItem);
	}

	/**
	 * delete NursingPlanServiceItem
	 */
	@Transactional
	public void deleteNursingPlanServiceItem(Long planId) {
		if (planId != null) {
			StringBuilder query = new StringBuilder("delete from NursingPlanServiceItem rp where rp.plan.id = ?1");
			this.em.createQuery(query.toString()).setParameter(1, planId).executeUpdate();
		}
	}

	/**
	 * update NursingPlanServiceItem
	 */
	@Transactional
	public void updateNursingPlanServiceItemStatus(Long planId) {
		if (planId != null) {
			StringBuilder query = new StringBuilder(
					"update  NursingPlanServiceItem rp set rp.delStatus=1 where rp.plan.id = ?1 and rp.delStatus=?2 ");
			this.em.createQuery(query.toString()).setParameter(1, planId).setParameter(2, (short) 0).executeUpdate();
		}
	}

	/**
	 * 获取护工单前所需完成的planitem 弃用
	 */
	public Iterable<NursingPlanServiceItem> getStaffPlanItem(long userId) {
		Role role = userService.getRoleByUserId(userId);
		Date date = new Date();
		int weekTab = -1;
		int startTimeTab = -1;
		//weekTab = CommonUtil.getWeekOfDate(date);
		if (weekTab == 0) {
			weekTab = 7;
		}
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		int hour = Integer.parseInt(dateStr.substring(11, 13));
		int min = Integer.parseInt(dateStr.substring(14, 16));
		if (min < 30) {
			startTimeTab = hour * 2;
		} else {
			startTimeTab = hour * 2 + 1;
		}
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		List<NursingPlanServiceItem> dataList = new ArrayList<NursingPlanServiceItem>();

		List<Customer> customerList = this.em.createQuery(
				// "select c.customer from EmployeeCustomer c where c.employee
				// in (select u.employee from User u where u.id = ?1 ) "
				"select c from Customer c where c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))")
				.setParameter(1, (short) 1).setParameter(2, userId).getResultList();
		List<NursingPlanServiceItem> itemList = new ArrayList<NursingPlanServiceItem>();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingPlanServiceItem
			String query = "select c from NursingPlanServiceItem c JOIN FETCH c.plan plan "
					+ "where c.delStatus != ?1  and c.weekTab=:weekTab and plan.customer in(:olds) " + "and ( "
					+ "(plan.planEndTime is not null and plan.planStartTime <=:nowTime and plan.planEndTime>=:nowTime )"
					+ " or ( plan.planEndTime = null and plan.planStartTime <=:nowTime )" + " )";//
			itemList = this.em.createQuery(query).setParameter(1, (short) 1).setParameter("weekTab", weekTab)
					.setParameter("olds", customerList).setParameter("nowTime", CommonUtil.getCurrTimes())
					.getResultList();
		}
		for (NursingPlanServiceItem item : itemList) {
			if (item != null) {
				if (item.getItem().getItem().getRoleType() != null) {
					Long t1 = item.getItem().getItem().getRoleType().getId();
					Long t2 = role.getRoleType().getId();
					if (item.getItem().getItem().getRoleType().getId().longValue() == role.getRoleType().getId()
							.longValue()) {// item角色类型与当前staff 所属角色类型一致
						dataList.add(item);
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取护工单前所需完成的projectitem 不定时任务
	 */
	public Iterable<NursingProjectServiceItem> getStaffProjectItem(long userId) {
		// Role role = userService.getRoleByUserId(userId);//获取user对应角色
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and c.customerStatus is not null and ( c.customerStatus.typecode=?3 or c.customerStatus.typecode=?4 ) "
						+ " and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ " and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ " and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1)
				.setParameter(2, userId).setParameter(3, "customerStatusIn").setParameter(4, "customerStatusTry")
				.getResultList();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
			StringBuilder queryItem = new StringBuilder(
					"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
							+ "where item.delStatus != ?1 and project.customer in(:olds) ");
			List<NursingProjectServiceItem> list = this.em.createQuery(queryItem.toString()).setParameter(1, (short) 1)
					.setParameter("olds", customerList).getResultList();
			for (int i = 0; i < list.size(); i++) {
				NursingProjectServiceItem item = list.get(i);
				if (item == null) {
					logger.debug("null-----------------------------------------------");
				} else {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, userId)
							.getResultList();
					if (serviceTypeList.size() > 0) {
						if ("countTypeByFrequency".equals(item.getItem().getCountType().getTypecode())) {
							// 修改为item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
							if (item.getItem().getServiceType() != null) {
								if (serviceTypeList.contains(item.getItem().getServiceType().getTypecode())) {
									itemList.add(item);
								}
							}
						} // end count
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 扫码 直接获取 customer projectitem
	 */
	public Iterable<NursingProjectServiceItem> getCustomerProjectItem(long customerId) {
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			long userId = ActionContextHolder.getContext().getUser().getId();
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			if (customerList.size() > 0) {
				// 获取老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
				StringBuilder queryItem = new StringBuilder(
						"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
								+ "where item.delStatus != ?1 and project.customer.id in(:olds) ");
				List<NursingProjectServiceItem> list = this.em.createQuery(queryItem.toString())
						.setParameter(1, (short) 1).setParameter("olds", customerList).getResultList();
				for (int i = 0; i < list.size(); i++) {
					NursingProjectServiceItem item = list.get(i);
					if (item == null) {
						logger.debug("null-----------------------------------------------");
					} else {
						StringBuilder queryRelation = new StringBuilder(
								"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
						List<String> serviceTypeList = this.em.createQuery(queryRelation.toString())
								.setParameter(1, userId).getResultList();
						if (serviceTypeList.size() > 0) {
							if ("countTypeByFrequency".equals(item.getItem().getCountType().getTypecode())) {
								// 修改为item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
								if (item.getItem().getServiceType() != null) {
									if (serviceTypeList.contains(item.getItem().getServiceType().getTypecode())) {
										itemList.add(item);
									}
								}
							} // end count
						} // end serviceTypeList
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 获取nursingproject
	 */
	public NursingProject getProjectByCustomer(Customer customer) {
		Long id = customer.getId();
		List resultList = this.em
				.createQuery("select c from NursingProject c where c.delStatus!=1 and c.customer.id = ?1 ")
				.setParameter(1, id).getResultList();
		NursingProject u = null;
		if (resultList.size() > 0) {
			u = (NursingProject) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取没有分组的护工
	 */
	public Iterable<Employee> getEmployeeListFilterGroup() {
		StringBuilder queryStaff = new StringBuilder(
				"select c from Employee c where c.delStatus != ?1 and c.tenant.id=?3 and c not in ( select p.employee from EmployeeNursingGroup p where p.delStatus != ?2 and  p.tenant.id=?3) ");
		List dataList = this.em.createQuery(queryStaff.toString()).setParameter(1, (short) 1).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取nursinglevel
	 */
	public NursingLevel getNursingLevelByResult(EvaluateResult result) {
		Integer score = Integer.parseInt(result.getScore());
		StringBuilder queryLevel = new StringBuilder(
				"select c from NursingLevel c where c.delStatus != ?1 and c.lowScore <= ?2 and c.highScore >=?2 and c.tenant.id=?3 ");
		List resultList = this.em.createQuery(queryLevel.toString()).setParameter(1, (short) 1).setParameter(2, score)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取nurseGroup
	 */
	public NurseGroup getNurseGroupById(Long id) {
		StringBuilder query = new StringBuilder("select c from NurseGroup c where c.id = ?1 and c.delStatus != ?2");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id).setParameter(2, (short) 1)
				.getResultList();
		NurseGroup u = null;
		if (resultList.size() > 0) {
			u = (NurseGroup) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取nurseGroup
	 */
	public NurseGroup getNurseGroupByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from NurseGroup c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseGroup u = null;
		if (resultList.size() > 0) {
			u = (NurseGroup) resultList.get(0);
		}
		return u;
	}

	@Transactional
	public void deleteNursrGroup(Long id) {
		if (id != null) {
			StringBuilder queryBed = new StringBuilder("delete from BedNurseGroup rp where rp.group.id = ?1");
			this.em.createQuery(queryBed.toString()).setParameter(1, id).executeUpdate();

			StringBuilder queryStaff = new StringBuilder("delete from EmployeeNursingGroup rp where rp.group.id = ?1");
			this.em.createQuery(queryStaff.toString()).setParameter(1, id).executeUpdate();
		}
	}

	/**
	 * 获取
	 */
	public List<WorkTimeSetting> getWorkTimeSettingByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from WorkTimeSetting c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();

		return resultList;
	}

	/**
	 * 获取
	 */
	public WorkTimeSetting getWorkTimeSettingById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from WorkTimeSetting c where c.id = ?1 and c.delStatus != ?2 ");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id).setParameter(2, (short) 1)
				.getResultList();
		WorkTimeSetting u = null;
		if (resultList.size() > 0) {
			u = (WorkTimeSetting) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NursingLevel
	 */
	public NursingLevel getNursingLevelById(Long id) {
		StringBuilder query = new StringBuilder("select c from NursingLevel c where c.id = ?1 and c.delStatus != ?2");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id).setParameter(2, (short) 1)
				.getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NursingLevel
	 */
	public NursingLevel getNursingLevelByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from NursingLevel c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name).setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NurseGroup bed处于试住 入住
	 */
	public List<NurseGroup> getNurseGroupByCustomerName(String name) {
		StringBuilder queryBed = new StringBuilder(
				"select c.bed from Customer c where  c.delStatus != ?1 and c.tenant.id=?2 " + "and c.name like '%"
						+ name + "%' " + "and (c.bed.status.typecode=?4 or c.bed.status.typecode=?3 ) ");
		List bedList = this.em.createQuery(queryBed.toString()).setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(4, CommonConstants.DICTTYPE.BED_STATUS_3.label())
				.setParameter(3, CommonConstants.DICTTYPE.BED_STATUS_2.label()).getResultList();
		List dataList = new ArrayList<>();
		if (bedList != null && bedList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from BedNurseGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.bed in (:beds) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId()).setParameter("beds", bedList)
					.getResultList();
		}
		return dataList;
	}

	/**
	 * 获取NurseGroup
	 */
	public List<NurseGroup> getNurseGroupByStaffName(String name) {
		StringBuilder queryStaff = new StringBuilder(
				"select c from Employee c where c.delStatus != ?1 and c.tenant.id=?2 and c.name like '%" + name
						+ "%' ");
		List staffList = this.em.createQuery(queryStaff.toString()).setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		List dataList = new ArrayList<>();
		if (staffList != null && staffList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from EmployeeNursingGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.employee in (:staffs) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId()).setParameter("staffs", staffList)
					.getResultList();
		}
		return dataList;
	}

	/**
	 * 获取NurseGroup
	 */
	public List<NurseGroup> getNurseGroupByCustomer(Customer customer) {
		StringBuilder queryBed = new StringBuilder(" select c.bed from Customer c where c.id = ?1 ");
		List bedList = this.em.createQuery(queryBed.toString()).setParameter(1, customer.getId()).getResultList();
		List dataList = new ArrayList<>();
		if (bedList != null && bedList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from BedNurseGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.bed in (:beds) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId()).setParameter("beds", bedList)
					.getResultList();
		}
		return dataList;
	}

	/**
	 * 摘取数据
	 */

	public List getCustomersFromCustomerNursingPlan(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() > 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (customers.contains(detail.getCustomer())) {

				} else {
					customers.add(detail.getCustomer());
				}
			}
		}
		return customers;
	}

	/**
	 * 摘取数据
	 */

	public Map getCustomerPlanDetailDatas(CustomerNursingPlan record) {
		// 删除原有数据
		Map<Object, List> detailData = new HashMap<>();
		if (record.getDetails() != null && record.getDetails().size() > 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detailData.containsKey(detail.getCustomer())) {

				} else {
					detailData.put(detail.getCustomer(), new ArrayList<>());
				}
				detailData.get(detail.getCustomer()).add(detail);
			}
		}
		return detailData;
	}

	/**
	 * 删除日护理计划 （日计划或者周计划）
	 */
	@Transactional
	public void deletePlanDayDetailByRecord(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Integer weekTab = record.getWeekTab();
		String periodType = "";
		if ("week".equals(record.getItemType())) {
			periodType = "periodWeek";
		}
		if ("day".equals(record.getItemType())) {
			periodType = "periodDay";
		}
		if (customers != null && customers.size() > 0) {
			List<NursingPlanDetail> dataList = new ArrayList<>();
			StringBuilder queryDetail = new StringBuilder(
					"select  c from  NursingPlanDetail c where c.customer is not null  "
							+ " and c.customer.id in (:olds) "
							+ " and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab=?3 "
							+ " and c.item.item.period.typecode=?4)");
			dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, record.getYearTab())
					.setParameter(2, record.getWeekIndex()).setParameter(3, weekTab).setParameter(4, periodType)
					.setParameter("olds", customers).getResultList();
			if (dataList.size() > 0) {
				StringBuilder query = new StringBuilder(" delete from  NursingPlanDetail c where c in (:dataList) ");
				this.em.createQuery(query.toString()).setParameter("dataList", dataList).executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 记录当天所有计划
	 */
	@Transactional
	public void deletePlanDetailByRecord(CustomerNursingPlan record) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Date now = new Date();
		Integer weekTab = CommonUtil.getWeek(now);
		if (weekTab == 0)
			weekTab = 7;
		int weekIndex = CommonUtil.getWeekIndexFromSun(now);
		if (customers != null && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null " + "and c.customer.id in (:olds) ");
			// 验证是所传周是不是当前周 是的话今天以前几天数据不删
			if (weekIndex == record.getWeekIndex()) {// 当前周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab>?3) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter(3, weekTab).setParameter("olds", customers)
						.executeUpdate();
			} else {// 以后几周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 ) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter("olds", customers).executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 未来几周
	 */
	@Transactional
	public void deletePlanDetailNextWeeks(CustomerNursingPlan record, int weekNum) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		if (customers != null && customers.size() > 0) {
			Map<Integer, String> dateTab = new HashMap<>();
			dateTab.put(0, record.getYearTab() + "," + record.getWeekIndex());
			for (Integer i = 0; i < weekNum + 1; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder("delete from  NursingPlanDetail c where c.customer is not null "
					+ "and c.customer.id in (:olds) " + "and " + " (" + " ( c.yearTab=?1 and c.weekIndex=?2 ) or"
					+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or" + " ( c.yearTab=?5 and c.weekIndex=?6 ) or"
					+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + " )");
			Integer t = Integer.valueOf(dateTab.get(1).split(",")[0]);
			this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
					.setParameter(2, record.getWeekIndex()).setParameter(3, t)
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1])).setParameter("olds", customers)
					.executeUpdate();
		}
	}

	/**
	 * 删除未来四周护理计划
	 */
	@Transactional
	public void deletePlanDetailNextWeeksByCustomer(Customer customer, int weekNum) {
		// 删除原有数据
		if (weekNum > 0 && customer != null) {
			Map<Integer, String> dateTab = new HashMap<>();
			int yearNow = (new Date().getYear() + 1900);
			int weekIndexNow = CommonUtil.getWeekIndexFromSun(new Date());// 以周末为第一天当前是第几周
			if (weekIndexNow + 1 > 52) {
				dateTab.put(0, (yearNow + 1) + "," + 1);
			} else {
				dateTab.put(0, yearNow + "," + (weekIndexNow + 1));
			}
			for (Integer i = 0; i < weekNum; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder("delete from  NursingPlanDetail c where c.customer is not null "
					+ "and c.customer.id =?9  " + "and (" + " ( c.yearTab=?1 and c.weekIndex=?2 ) or "
					+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or " + " ( c.yearTab=?5 and c.weekIndex=?6 ) or "
					+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + "    )");
			this.em.createQuery(query.toString()).setParameter(1, Integer.valueOf(dateTab.get(0).split(",")[0]))
					.setParameter(2, Integer.valueOf(dateTab.get(0).split(",")[1]))
					.setParameter(3, Integer.valueOf(dateTab.get(1).split(",")[0]))
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1])).setParameter(9, customer.getId())
					.executeUpdate();
		}
	}

	/**
	 * 删除护理计划模版
	 */
	@Transactional
	public void deletePlanItemByCustomerId(Long customerId) {
		Date now = new Date();
		int yearNow = (now.getYear() + 1900);
		int weekIndexNow = CommonUtil.getWeekIndexFromSun(now);
		int weekTab = CommonUtil.getWeek(now);
		int deleteNowFlag = checkPlanDetailNowRelations(customerId, yearNow, weekIndexNow, weekTab);
		// 删除今天以后当周的护理计划
		StringBuilder queryNow = new StringBuilder("delete from  NursingPlanDetail c where c.customer is not null "
				+ " and c.customer.id =?1 and c.yearTab=?2 and ( c.weekIndex >?3  or ( c.weekIndex =?3 ");
		if (deleteNowFlag == 0) {
			queryNow.append(" and c.weekTab >=?4 ))");
		} else {
			queryNow.append(" and c.weekTab >?4 ))");
		}
		this.em.createQuery(queryNow.toString()).setParameter(1, customerId).setParameter(2, yearNow)
				.setParameter(3, weekIndexNow).setParameter(4, weekTab).executeUpdate();
		// 删除原有模版
		StringBuilder query = new StringBuilder(
				"delete from  NursingPlanServiceItem c  where c.customer is not null and c.customer.id= ?1 ");
		this.em.createQuery(query.toString()).setParameter(1, customerId).executeUpdate();
	}

	/**
	 * 删除护理计划模版 弃用
	 */
	@Transactional
	public void deletePlanItem(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = getCustomersFromCustomerNursingPlan(record);
		if (record.getDetails() != null && record.getDetails().size() > 0 && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanServiceItem c  where c.customer is not null and c.customer in (:olds)");
			this.em.createQuery(query.toString()).setParameter("olds", customers).executeUpdate();
		}
	}

	/**
	 * 产生护理计划模版
	 */
	public void createPlanItem(CustomerNursingPlan record) {
		List dataList = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					NursingPlanServiceItem item = new NursingPlanServiceItem();
					item.setCustomer(detail.getCustomer());
					item.setDelStatus((short) 0);
					item.setItem(detail.getItem());
					item.setWeekTab(detail.getWeekTab());
					item.setStartTimeTab(detail.getStartTimeTab());
					item.setTenant(detail.getCustomer().getTenant());
					dataList.add(item);
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);// 产生模版
			}
		}
	}

	/**
	 * 当天护理计划是否执行过
	 */
	public int checkPlanDetailNowRelations(Long customerId, int yearTab, int weekIndex, int weekTab) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  NursingPlanExecute c where c.detail is not null and c.detail.customer is not null "
						+ " and c.detail.customer.id =?1 and c.detail.yearTab=?2 and c.detail.weekIndex =?3 and c.detail.weekTab =?4 ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, customerId).setParameter(2, yearTab)
				.setParameter(3, weekIndex).setParameter(4, weekTab).getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}

	/**
	 * 复制护理计划
	 */
	public void copyPlanToNextWeeks(CustomerNursingPlan record, int weeksNum) { // record数据是下周数据
		logger.debug("start copy CustomerNursingPlan " + CommonUtil.getCurrTimeForString() + " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					for (int i = 0; i < weeksNum + 2; i++) {
						if (i == 0) {
							dateTemp = new Date();// 本周 已经存在 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生下三周的 年 周 序号
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						if (i > 1) {
							NursingPlanDetail data = new NursingPlanDetail();
							data.setCreateDateTime(CommonUtil.getCurrTimes());
							data.setCustomer(detail.getCustomer());
							data.setItem(detail.getItem());
							data.setDelStatus((short) 0);
							data.setStartTimeTab(detail.getStartTimeTab());
							data.setTenant(detail.getCustomer().getTenant());
							data.setWeekTab(detail.getWeekTab());// 周几
							data.setWeekIndex(weekIndex);// 第几周
							data.setYearTab(year);
							dataList.add(data);
						}
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后三周
			}
		}
	}

	/**
	 * 复制产生未来几周护理计划
	 */
	public void copyPlanToNextWeeks(CustomerNursingPlanModel model, int weeksNum) {
		logger.debug(
				"start copy CustomerNursingPlanModel " + CommonUtil.getCurrTimeForString() + " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (model.getItems() != null && model.getItems().size() != 0) {
			for (NursingPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					for (int i = 0; i <= weeksNum; i++) {
						if (i == 0) {
							dateTemp = new Date();// i=0 本周 不复制 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
						int weekTab = CommonUtil.getWeek(dateTemp);
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						// 复制本周护理计划
						if (i == 0) {
							// 验证当天护理计划是否被执行过
							int copyNowFlag = checkPlanDetailNowRelations(item.getCustomer().getId(), year, weekIndex,
									weekTab);
							if (item.getWeekTab() != null && item.getWeekTab() >= weekTab) {// 周计划
								int copyFlag = 1;
								// 当天已有计划被执行过不复制
								if (item.getWeekTab() == weekTab && copyNowFlag != 0) {
									copyFlag = 0;
								}
								if (copyFlag == 1) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(item.getWeekTab());// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								}
							}
							if (item.getWeekTab() == null) { // 日计划每天都有
								int k = weekTab + 1;
								if (copyNowFlag == 0) {
									k = weekTab;
								}
								for (; k < 7; k++) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						}
						// 复制未来周护理计划
						if (i > 0) {
							if (item.getWeekTab() != null) {// 周计划
								NursingPlanDetail data = new NursingPlanDetail();
								data.setCreateDateTime(CommonUtil.getCurrTimes());
								data.setCustomer(item.getCustomer());
								data.setItem(item.getItem());
								data.setDelStatus((short) 0);
								data.setStartTimeTab(item.getStartTimeTab());
								data.setTenant(item.getTenant());
								data.setWeekTab(item.getWeekTab());// 周几
								data.setWeekIndex(weekIndex);// 第几周
								data.setYearTab(year);
								dataList.add(data);
							} else { // 日计划每天都有
								for (int k = 0; k < 7; k++) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						} // end if i
					} // end for i
				} // end if item
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后4周
			}
		}
	}

	/**
	 * 获取customer 的 定时服务项目
	 */
	public Iterable<NursingPlanDetail> getTimeServiceItemByCID(long customerId) {
		// Role role = userService.getRoleByUserId(userId);
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			long userId = ActionContextHolder.getContext().getUser().getId();
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
			if (customerList.size() > 0) {
				// 获取当前护工所护理老人对应的 NursingPlanServiceItem
				StringBuilder queryDetail = new StringBuilder("select c from NursingPlanDetail c "
						+ "where c.delStatus != ?1 and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in(:olds) ");
				itemList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(2, year)
						.setParameter(3, weekIndex).setParameter(4, week).setParameter("olds", customerList)
						.getResultList();
			}
			for (NursingPlanDetail item : itemList) {
				if (item != null) {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, userId)
							.getResultList();
					// 判断item所属position和 user所关联Employee position一致 huibati
					if (item.getItem().getItem().getServiceType() != null
							&& !"countTypeByFrequency".equals(item.getItem().getItem().getCountType().getTypecode())) {
						if (serviceTypeList.contains(item.getItem().getItem().getServiceType().getTypecode())) {// item角色类型与当前staff所属角色类型一致
																												// -----判断item所属position和
																												// user所关联Employee
																												// position一致
							dataList.add(item);
						}
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取user的定时服务项目
	 */
	public Iterable<NursingPlanDetail> getTimeServiceItemByUID(long userId) {
		// Role role = userService.getRoleByUserId(userId);
		Date now = new Date();
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
		Integer year = now.getYear() + 1900;
		Integer week = CommonUtil.getWeek(now);
		// if(week==0) week=7;
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?3 and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1)
				.setParameter(2, userId).setParameter(3, "customerStatusOut").getResultList();//
		List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingPlanServiceItem
			StringBuilder queryDetail = new StringBuilder("select c from NursingPlanDetail c "
					+ "where c.delStatus != ?1 and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer in(:olds) ");
			itemList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(2, year)
					.setParameter(3, weekIndex).setParameter(4, week).setParameter("olds", customerList)
					.getResultList();
		}
		for (NursingPlanDetail item : itemList) {
			if (item != null) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
				List<String> serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, userId)
						.getResultList();
				// 判断item所属position和 user所关联Employee position一致 huibati
				if (item.getItem().getItem().getServiceType() != null
						&& !"countTypeByFrequency".equals(item.getItem().getItem().getCountType().getTypecode())) {
					if (serviceTypeList.contains(item.getItem().getItem().getServiceType().getTypecode())) {
						dataList.add(item);
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取不定时服务
	 */
	public Iterable<NursingPlanDetail> getCountServiceItem(long userId) {
		Role role = userService.getRoleByUserId(userId);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(new Date());//
		Integer year = new Date().getYear() + 1900;
		Integer week = CommonUtil.getWeek(new Date());
		// if(week==0) week=7;
		List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		StringBuilder queryCustomer = new StringBuilder("select c from Customer c where c.delStatus != 1 "
				+ "and c.bed in ( select b from Bed b where b.delStatus != ?1 and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
				+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
				+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1)
				.setParameter(2, userId).getResultList();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
			StringBuilder queryDetail = new StringBuilder(
					"select c from NursingPlanDetail c " + "where c.delStatus != ?1 "
							+ "and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 "
							+ "and c.customer in(:olds) ");
			List<NursingPlanDetail> list = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
					.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
					.setParameter("olds", customerList).getResultList();
			for (int i = 0; i < list.size(); i++) {
				NursingPlanDetail item = list.get(i);
				if (item == null) {
					logger.debug("null-----------------------------------------------");
				} else {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c "
									+ "where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, userId)
							.getResultList();
					if (serviceTypeList.size() > 0) {
						if ("countTypeByFrequency".equals(item.getItem().getItem().getCountType().getTypecode())) {
							// 修改为
							// item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
							if (item.getItem().getItem().getServiceType() != null) {
								if (serviceTypeList.contains(item.getItem().getItem().getServiceType().getTypecode())) {
									itemList.add(item);
								}
							}
						} // end count
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 验证护理等级关联关系
	 */
	public int checkLevelRelations(NursingLevel level) {
		int flag = 0;
		Long id = level.getId();
		List projectList = new ArrayList<>();
		projectList = this.em
				.createQuery(
						"select c from NursingProject c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1).setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();

		List scopeList = new ArrayList<>();
		scopeList = this.em
				.createQuery(
						"select c from EvaluateScoreScope c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1).setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();

		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						"select c from EvaluateResult c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1).setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();
		flag += projectList.size() + scopeList.size() + resultList.size();

		return flag;
	}

	/**
	 * 获取老人相应周的护理计划 数量
	 */
	public Iterable<NursingPlanDetail> getCustomerNursePlanNum(long customerId, Integer yearTab, Integer weekIndex) {
		Map<Integer, NursingPlanDetail> dataMap = new HashMap<Integer, NursingPlanDetail>();// 每天
																							// 日计划
																							// 周计划相应数量
		Map<NursingProjectServiceItem, Integer> detailWeekCounts = new HashMap<NursingProjectServiceItem, Integer>();// 统计周计划本周安排次数
		int tempId = 7;
		for (int i = 0; i < 7; i++) {// 0-6 对应周末--周六
			NursingPlanDetail detail = new NursingPlanDetail();
			detail.setYearTab(yearTab);// 年份
			detail.setWeekIndex(weekIndex);// 第几周
			detail.setWeekTab(i);// 周几
			detail.setWeekPlanNum(0);
			detail.setDayPlanNum(0);
			detail.setId(new Long(i));
			dataMap.put(i, detail);
		}
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		StringBuilder queryDetail = new StringBuilder("select c from NursingPlanDetail c "
				+ "where c.delStatus != ?1 and c.yearTab=?2 and c.weekIndex=?3  and c.customer.id= ?4 ");
		dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(2, yearTab)
				.setParameter(3, weekIndex).setParameter(4, customerId).getResultList();
		String weekItemName = " ";
		String dayItemName = " ";
		for (NursingPlanDetail detail : dataList) {
			if (detail != null) {
				if ("periodWeek".equals(detail.getItem().getItem().getPeriod().getTypecode())) {// 周计划
					if (detailWeekCounts.containsKey(detail.getItem())) {
						detailWeekCounts.put(detail.getItem(), detailWeekCounts.get(detail.getItem()) + 1);
					} else {
						detailWeekCounts.put(detail.getItem(), 1);
					}
					if (weekItemName.contains(detail.getItem().getItem().getName() + ",")) {

					} else {
						weekItemName += detail.getItem().getItem().getName() + ",";
					}
					int weekPlanNum = dataMap.get(detail.getWeekTab()).getWeekPlanNum();
					dataMap.get(detail.getWeekTab()).setWeekPlanNum(weekPlanNum + 1);
				}
				if ("periodDay".equals(detail.getItem().getItem().getPeriod().getTypecode())) {// 天计划
					if (dayItemName.contains(detail.getItem().getItem().getName() + ",")) {

					} else {
						dayItemName += detail.getItem().getItem().getName() + ",";
					}
					int dayPlanNum = dataMap.get(detail.getWeekTab()).getDayPlanNum();
					dataMap.get(detail.getWeekTab()).setDayPlanNum(dayPlanNum + 1);
				}
			}
		}
		if (dayItemName.length() > 0) {
			dayItemName = dayItemName.substring(0, dayItemName.length() - 1);
		}
		if (weekItemName.length() > 0) {
			weekItemName = weekItemName.substring(0, weekItemName.length() - 1);
		}
		dataMap.get(0).setRemark(weekItemName + "@" + dayItemName);
		if (detailWeekCounts.size() > 0) {
			Set<NursingProjectServiceItem> keySet = detailWeekCounts.keySet();
			for (NursingProjectServiceItem key : keySet) {
				NursingPlanDetail detail = new NursingPlanDetail();
				detail.setItem(key);
				detail.setWeekCounts(detailWeekCounts.get(key));
				detail.setId(new Long(tempId));
				dataMap.put(tempId, detail);
				tempId++;
			}
		}
		return new ArrayList<NursingPlanDetail>(dataMap.values());
	}

	/**
	 * 验证serviceItem是否有关联
	 */
	public int checkServiceItemRelations(CustomerServiceItem item) {
		int flag = 0;
		Long id = item.getId();
		List projectList = new ArrayList<>();
		projectList = this.em
				.createQuery("select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, id).getResultList();
		List levelList = new ArrayList<>();
		levelList = this.em
				.createQuery("select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, id).getResultList();
		flag += projectList.size() + levelList.size();
		return flag;
	}

	/**
	 * 验证foodlevel是否有关联
	 */
	public int checkFoodLevelRelations(DicttypeTenant level) {
		int flag = 0;
		Long id = level.getId();
		List levelList = new ArrayList<>();
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != ?1  and c.diningStandard.id=?2 ");
		levelList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1).setParameter(2, id)
				.getResultList();
		flag += levelList.size();
		return flag;
	}

	/**
	 * 验证project是否和plandetail有关联
	 */
	public int checkProjectRelations(NursingProject project) {
		int flag = 0;
		Long id = project.getId();
		List projectList = new ArrayList<>();
		StringBuilder queryDetail = new StringBuilder(
				"select c from NursingPlanDetail c where c.delStatus != ?1  and c.item.project.id=?2 ");
		projectList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(2, id)
				.getResultList();
		flag += projectList.size();
		return flag;
	}

	/**
	 * @author huibati 删除Project 2017年7月19日
	 */
	@Transactional
	public void deleteNursingProject(NursingProject project) {
		StringBuilder queryItem = new StringBuilder(
				"update  NursingProjectServiceItem rp set rp.delStatus=1 where rp.project.id = ?1 and rp.delStatus=?2 ");
		this.em.createQuery(queryItem.toString()).setParameter(1, project.getId()).setParameter(2, (short) 0)
				.executeUpdate();
		StringBuilder queryProject = new StringBuilder(
				"update  NursingProject rp set rp.delStatus=1 where rp.id = ?1 ");
		this.em.createQuery(queryProject.toString()).setParameter(1, project.getId()).executeUpdate();
	}

	/**
	 * 验证projectitem是否和plandetail有关联
	 */
	public int checkProjectItemRelations(List<Long> itemIds, int dateTime) {
		int flag = 0;
		Date date = new Date(dateTime * 1000l);
		int year = date.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(date);
		int weekIndex = CommonUtil.getWeekIndexFromSun(date);
		List projectList = new ArrayList<>();
		StringBuilder queryDetail = new StringBuilder(
				"select c from NursingPlanDetail c where c.delStatus != ?1 " + " and ("
						+ "  ( c.yearTab>?3 ) or ( c.yearTab=?3 and c.weekIndex > ?4  ) or ( c.yearTab=?3 and c.weekIndex = ?4 and c.weekTab >?5 ) "
						+ " )" + "  and c.item.id in (:ids) ");
		projectList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(3, year)
				.setParameter(4, weekIndex).setParameter(5, weekTab).setParameter("ids", itemIds).getResultList();
		flag += projectList.size();
		return flag;
	}

	/**
	 * 获取
	 */
	public NurseMerch getNurseMerchByCode(NurseMerch data) {
		StringBuilder query = new StringBuilder(
				"select c from NurseMerch c where c.code = ?1 and c.delStatus != ?2 and c.type.typecode = ?3 and c.tenant.id = ?4 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getCode()).setParameter(2, (short) 1)
				.setParameter(3, data.getType().getTypecode())
				.setParameter(4, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseMerch ct = null;
		if (dataList.size() > 0) {
			ct = (NurseMerch) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public NurseMerch getNurseMerchByCodeFilterId(NurseMerch data) {
		StringBuilder query = new StringBuilder(
				"select c from NurseMerch c where c.code = ?1 and c.delStatus != ?2  and c.id != ?3 and c.type.typecode = ?4 and c.tenant.id = ?5  ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getCode()).setParameter(2, (short) 1)
				.setParameter(3, data.getId()).setParameter(4, data.getType().getTypecode())
				.setParameter(5, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseMerch ct = null;
		if (dataList.size() > 0) {
			ct = (NurseMerch) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取老人 projectitem 不定时任务
	 */
	public List<NursingProjectServiceItem> getProjectItemByCustomer(List<Long> customerList, String positonType,
			String itemType) {
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		List<String> serviceTypeList = new ArrayList<>();
		if (customerList != null && customerList.size() > 0) {
			// 相应岗位对应的服务项目类别
			if (positonType != null && !"".equals(positonType)) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position.typecode =?1");
				serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, positonType)
						.getResultList();
			}
			serviceTypeList.add(itemType);
			// 老人对应的 NursingProjectServiceItem
			StringBuilder queryItem = new StringBuilder(
					"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
							+ "where item.delStatus != ?1 and project.customer.id in (:olds) and item.item.countType.typecode = ?3");
			itemList = this.em.createQuery(queryItem.toString()).setParameter(1, (short) 1)
					.setParameter("olds", customerList).setParameter(3, "countTypeByFrequency").getResultList();
			if (serviceTypeList.size() > 0 && itemList.size() > 0) {
				for (Iterator<NursingProjectServiceItem> it = itemList.iterator(); it.hasNext();) {
					NursingProjectServiceItem item = it.next();
					if (!serviceTypeList.contains(item.getItem().getServiceType().getTypecode())) {
						it.remove();
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 获取老人 NursingPlanDetail 定时任务
	 */
	public List<NursingPlanDetail> getPlanDetailByCustomer(List<Long> customerList, String positonType,
			String itemType) {
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		List<String> serviceTypeList = new ArrayList<>();
		if (customerList != null && customerList.size() > 0) {
			// 相应岗位对应的服务项目类别
			if (positonType != null && !"".equals(positonType)) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position.typecode =?1");
				serviceTypeList = this.em.createQuery(queryRelation.toString()).setParameter(1, positonType)
						.getResultList();
			}
			serviceTypeList.add(itemType);
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			// 获取老人对应的 NursingPlanDetail
			StringBuilder queryDetail = new StringBuilder("select c from NursingPlanDetail c "
					+ " where c.delStatus != ?1 and c.item.project.delStatus!=1 "
					+ " and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in (:olds) "
					+ " and c.customer.id = c.item.project.customer.id" + " and c.item.item.countType.typecode != ?6 ");
			dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1).setParameter(2, year)
					.setParameter(3, weekIndex).setParameter(4, week).setParameter("olds", customerList)
					.setParameter(6, "countTypeByFrequency").getResultList();
			if (serviceTypeList.size() > 0 && dataList.size() > 0) {
				for (Iterator<NursingPlanDetail> it = dataList.iterator(); it.hasNext();) {
					NursingPlanDetail detail = it.next();
					if (!serviceTypeList.contains(detail.getItem().getItem().getServiceType().getTypecode())) {
						it.remove();
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取老人 CustomerDrugProject 用药计划
	 */
	public List<CustomerDrugProject> getDrugProjectByCustomer(List<Long> customerList, String positonType,
			String itemType) {
		List<CustomerDrugProject> dataList = new ArrayList<CustomerDrugProject>();
		// zhuanyehuli 查看用药计划
		// if (positonType == null || !"postType5".equals(positonType)) {
		if (itemType != null && "serviceType1".equals(itemType)) {
			if (customerList != null && customerList.size() > 0) {
				StringBuilder query = new StringBuilder(
						"select  c  from CustomerDrugProject c  where c.delStatus != ?1  "
								+ " and  c.customerDrug.customer.id in (:olds)");
				dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
						.setParameter("olds", customerList).getResultList();
			}
		}
		return dataList;
	}

	/**
	 * 获取 老人 定时任务,不定时任务以及用药计划
	 */
	public List<SpecService> getNursingServiceByCustomer(Long customerId, Long userId, Long queryStartDate,
			Long queryEndDate, String positonType, String itemType) {
		String curTime = CommonUtil.getCurrTimeForString();// 当日日期
		Integer curTimeStart = 0;
		Integer curTimeEnd = 0;
		Integer curMonTimeStart = 0;
		Integer curMonTimeEnd = 0;
		try {
			curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 00:00:00");
			curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 23:59:59");
			// curMonTimeStart = CommonUtil
			// .strToIntegerTime(CommonUtil.getMonthFirstDayForString().substring(0,
			// 10) + " 00:00:00");
			// curMonTimeEnd = CommonUtil
			// .strToIntegerTime(CommonUtil.getMonthLastDayForString().substring(0,
			// 10) + " 23:59:59");
		} catch (ParseException e) {
			logger.error("timer error " + e);
		}
		List<SpecService> dataList = new ArrayList<SpecService>();
		List<NursingPlanDetail> detailList = new ArrayList<NursingPlanDetail>();// 护理计划
		List<CustomerDrugProject> projectList = new ArrayList<CustomerDrugProject>();// 用药计划
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();// 不定时任务
		List<NursingPlanExecute> detailExeList = new ArrayList<NursingPlanExecute>();// 定时任务完成情况
		List<NursingPlanExecute> itemExeList = new ArrayList<NursingPlanExecute>();// 不定时任务完成情况
		List<CustomerDrugProjectExe> drugExeList = new ArrayList<CustomerDrugProjectExe>();// drug完成情况
		Map<String, CustomerDrugProjectExe> drugExeMap = new HashMap<>();// customerdrugid+@+计划用药时间
		Map<String, List<NursingPlanExecute>> planExeMap = new HashMap<>();// projextItemid+执行情况/projextItemid+#+planexedate+执行情况
		List<Long> customerList = new ArrayList<>();
		if (customerId != null) {
			customerList.add(customerId);
		} else {
			// 护理组所护理的老人
			customerList = getCustomerByUID(userId);
		}
		if (customerList != null && customerList.size() > 0) {
			Long idTemp = (long) 1;
			projectList = getDrugProjectByCustomer(customerList, positonType, itemType);
			if (projectList != null && projectList.size() > 0) {
				// 获取当日用药计划执行情况
				StringBuilder drugExe = new StringBuilder("select c from CustomerDrugProjectExe c "
						+ " where c.delStatus != ?1 and c.customerDrug.customer.id in (:olds) "
						+ " and c.createDateTime >= ?3 and c.createDateTime <= ?4 ");
				drugExeList = this.em.createQuery(drugExe.toString()).setParameter(1, (short) 1)
						.setParameter("olds", customerList).setParameter(3, curTimeStart).setParameter(4, curTimeEnd)
						.getResultList();
				// 拼接map,key:customerdrugid+@+计划用药时间
				for (int i = 0; i < drugExeList.size(); i++) {
					drugExeMap.put(drugExeList.get(i).getCustomerDrug().getId().toString() + "@"
							+ drugExeList.get(i).getUseDrugDate(), drugExeList.get(i));
				}
				// 拆分 CustomerDrugProject
				for (CustomerDrugProject project : projectList) {
					if (project != null && project.getUseDrugDate() != null && !"".equals(project.getUseDrugDate())) {
						String[] dates = project.getUseDrugDate().split(",");
						for (String date : dates) {
							if (date != null && date.matches("\\d+")) {
								CustomerDrugProjectItem projectTemp = new CustomerDrugProjectItem();
								BeanUtils.copyProperties(project, projectTemp);
								projectTemp.setUseDrugDate(date);
								projectTemp.setId(idTemp);
								projectTemp.setProject(project);
								SpecService temp = new SpecService();
								if (drugExeMap.containsKey(project.getCustomerDrug().getId() + "@" + date)) {
									temp.setDrugExe(drugExeMap.get(project.getCustomerDrug().getId() + "@" + date));
								}
								temp.setProject(projectTemp);
								temp.setId(idTemp);
								dataList.add(temp);
								idTemp++;
							} // end if date
						} // end for data
					} // end if project
				} // end for project
			}
			detailList = getPlanDetailByCustomer(customerList, positonType, itemType);
			itemList = getProjectItemByCustomer(customerList, positonType, itemType);
			// 获取当日任务planexe执行情况
			StringBuilder queryDetailExe = new StringBuilder("select c from NursingPlanExecute c "
					+ " where c.delStatus != ?1  and c.itemProject.project.customer.id in (:olds) "
					+ " and c.createDateTime >= ?3 and c.createDateTime <= ?4 ");
			detailExeList = this.em.createQuery(queryDetailExe.toString()).setParameter(1, (short) 1)
					.setParameter("olds", customerList).setParameter(3, curTimeStart).setParameter(4, curTimeEnd)
					.getResultList();
			// 拼接map,key:projextItemid(不定时)/projextItemid+#+planexedate(定时)
			if (detailExeList != null && detailExeList.size() > 0) {
				for (int i = 0; i < detailExeList.size(); i++) {
					if (detailExeList.get(i).getPlanExeDate() != null
							&& detailExeList.get(i).getPlanExeDate().matches("\\d+")) {
						List<NursingPlanExecute> exes = new ArrayList<>();
						exes.add(detailExeList.get(i));
						planExeMap.put(detailExeList.get(i).getItemProject().getId().toString() + "#"
								+ detailExeList.get(i).getPlanExeDate(), exes);
					} else {
						if (planExeMap.get(detailExeList.get(i).getItemProject().getId().toString()) == null) {
							List<NursingPlanExecute> exes = new ArrayList<>();
							exes.add(detailExeList.get(i));
							planExeMap.put(detailExeList.get(i).getItemProject().getId().toString(), exes);
						} else {
							planExeMap.get(detailExeList.get(i).getItemProject().getId().toString())
									.add(detailExeList.get(i));
						}
					}
				}
			}
			for (NursingPlanDetail detail : detailList) {
				if (detail != null && detail.getStartTimeTab() != null && !"".equals(detail.getStartTimeTab())) {
					SpecService temp = new SpecService();
					if (planExeMap.containsKey(detail.getItem().getId().toString() + "#" + detail.getStartTimeTab())) {
						temp.setItemExes(
								planExeMap.get(detail.getItem().getId().toString() + "#" + detail.getStartTimeTab()));
					}
					temp.setId(idTemp);
					temp.setItem(detail);
					dataList.add(temp);
					idTemp++;
				}
			} // end for detail
			for (NursingProjectServiceItem item : itemList) {
				if (item != null) {
					SpecService temp = new SpecService();
					if (planExeMap.containsKey(item.getId().toString())) {
						// temp.setItemExe(planExeMap.get(item.getId().toString()));
						temp.setItemExes(planExeMap.get(item.getId().toString()));
					}
					temp.setId(idTemp);
					temp.setProjectItem(item);
					dataList.add(temp);
					idTemp++;
				}
			} // end for item
				// 根据时间间隔进行筛选
			if (queryStartDate != null && queryEndDate != null) {
				for (Iterator<SpecService> it = dataList.iterator(); it.hasNext();) {
					SpecService spec = it.next();
					if (spec != null) {
						if (spec.getProjectItem() != null) {
							continue;
						}
						if (spec.getDate() >= queryStartDate && spec.getDate() <= queryEndDate) {

						} else {
							it.remove();
						}
					}
				}
			}
			// 按照时间排序
			Collections.sort(dataList);
		} // end if culist
		return dataList;
	}

	/**
	 * 获取user照料老人
	 */
	public List<Long> getCustomerByUID(long userId) {
		// huibati 获取 user对应 employee所对应的未请假的customer
		StringBuilder queryCustomer = new StringBuilder(
				"select c.id from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?3  and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ ")) and c not in ( select cl.customer from CustomerLeave cl where cl.delStatus != 1 and cl.tenant.id=c.tenant.id and cl.status=1)");
		List<Long> customerList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1)
				.setParameter(2, userId).setParameter(3, "customerStatusOut").getResultList();
		return customerList;
	}

	/**
	 * 验证医疗物品关联关系
	 */
	public int checkNurseMerchRelations(NurseMerch data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em.createQuery(" select c from ServiceMerch c where c.delStatus != ?1  and c.merch.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, data.getId()).getResultList();
		flag += resultList.size();
		return flag;
	}

	/**
	 * 获取ServiceFinishLevel
	 */
	public ServiceFinishLevel getFinishLevelByNameFilterId(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				"select c from ServiceFinishLevel c where c.name = ?1 and c.delStatus != ?2  and c.id != ?3 and c.tenant.id = ?4 and c.item.id = ?5 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getName()).setParameter(2, (short) 1)
				.setParameter(3, data.getId()).setParameter(4, ActionContextHolder.getContext().getTenantId())
				.setParameter(5, data.getItem().getId()).getResultList();
		ServiceFinishLevel nm = null;
		if (dataList.size() > 0) {
			nm = (ServiceFinishLevel) dataList.get(0);
		}
		return nm;
	}

	/**
	 * 获取ServiceFinishLevel
	 */
	public ServiceFinishLevel getFinishLevelByName(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				"select c from ServiceFinishLevel c where c.name = ?1 and c.delStatus != ?2  and c.tenant.id = ?4 and c.item.id = ?5 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getName()).setParameter(2, (short) 1)
				.setParameter(4, ActionContextHolder.getContext().getTenantId()).setParameter(5, data.getItem().getId())
				.getResultList();
		ServiceFinishLevel nm = null;
		if (dataList.size() > 0) {
			nm = (ServiceFinishLevel) dataList.get(0);
		}
		return nm;
	}

	/**
	 * 验证服务项完成情况关联关系
	 */
	public int checkFinishLevelRelations(ServiceFinishLevel data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						" select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		List resultLevelList = new ArrayList<>();
		resultLevelList = this.em
				.createQuery(
						" select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		flag += resultList.size() + resultLevelList.size();
		return flag;
	}

	/**
	 * 验证医疗物品相应服务项的关联关系
	 */
	public int checkServiceMerchRelations(ServiceMerch data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						" select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		List resultLevelList = new ArrayList<>();
		resultLevelList = this.em
				.createQuery(
						" select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		flag += resultList.size() + resultLevelList.size();
		return flag;
	}

	/**
	 * 新增执行情况，如为增值服务生成增值服务账单
	 */
	@Transactional
	public void addPlanExe(NursingPlanExecute exe) {
		dslJpaService.setEntityClass(NursingPlanExecute.class);
		if (exe.getId() == null) {
			dslJpaService.create(exe);
		} else {
			dslJpaService.update(exe);
		}
		CustomerServiceItem item = null;
		Customer customer = null;
		if (exe.getItemProject() != null) {
			item = exe.getItemProject().getItem();
			customer = exe.getItemProject().getProject().getCustomer();
		} else if (exe.getDetail() != null && exe.getDetail().getItem().getItem() != null) {
			item = exe.getDetail().getItem().getItem();
		}
		if (item != null) {
			if (item.getServiceValueType() != null && CommonConstants.DICTTYPE.SERVICEVALUETYPE_ZZ.label()
					.equals(item.getServiceValueType().getTypecode())) {
				String dayTime = CommonUtil.getCurrTimeForString();
				String year = dayTime.substring(0, 4);
				String month = dayTime.substring(5, 7);
				String remark = "";
				Double total = 0.0;
				// 服务对应的消耗品
				List<ServiceMerch> merchList = new ArrayList<>();
				merchList = this.em
						.createQuery(" select c from ServiceMerch c where c.delStatus != ?1  and c.item.id = ?2 ")
						.setParameter(1, (short) 1).setParameter(2, item.getId()).getResultList();
				remark += "医疗用品消耗:";
				for (ServiceMerch sm : merchList) {
					int mNum = 0;
					Double nPrice = 0.0;
					if (sm != null) {
						if (sm.getMerchNum() != null && sm.getMerch() != null && sm.getMerch().getPrice() != null) {
							mNum = sm.getMerchNum();
							nPrice = sm.getMerch().getPrice();
							total += mNum * nPrice;
							remark += " " + sm.getMerch().getName() + " 数量:" + sm.getMerchNum() + " 单价:" + nPrice
									+ "元;";
						}
					}
				}
				CustomerServiceBill bill = new CustomerServiceBill();
				bill.setCustomer(customer);
				bill.setBillYear(Integer.parseInt(year));
				bill.setBillMonth(Integer.parseInt(month));
				bill.setBillTime(CommonUtil.getCurrTimes());
				bill.setTenant(customer.getTenant());
				Double servicePrice = 0.0;
				if (item.getPrice() == null) {

				} else {
					servicePrice = Double.parseDouble(item.getPrice());
				}
				total += servicePrice;
				remark += "/n增值服务费用:" + item.getName() + " 价格:" + servicePrice + "元;";
				bill.setRemark(remark);
				bill.setTotal(total);
				bill.setExe(exe);
				dslJpaService.setEntityClass(CustomerServiceBill.class);
				dslJpaService.create(bill);
			}
		}
	}

	/**
	 * 护理计划是否执行过
	 */
	public int checkPlanDetailExeRelations(NursingPlanDetail data) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  NursingPlanExecute c where c.delStatus!=1 and c.detail is not null  "
						+ " and c.detail.id =?1  ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, data.getId()).getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}

	/**
	 * @author huibati 创建用药计划执行并修改老人剩余药量 2017年6月30日
	 */
	@Transactional
	public CustomerDrugProjectExe operateCustomerDrugProjectExe(CustomerDrugProjectExe exe) {
		if (exe.getId() == null) {
			// 验证是否执行过
			try {
				String curTime = CommonUtil.getCurrTimeForString();// 当日日期
				Integer curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 00:00:00");
				Integer curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 23:59:59");
				List<CustomerDrugProjectExe> exes = this.em
						.createQuery(
								" select c from CustomerDrugProjectExe c where c.delStatus != ?1  and c.drugProject.id = ?2 and c.useDrugDate = ?3 and c.createDateTime>= ?4 and c.createDateTime<= ?5")
						.setParameter(1, (short) 1).setParameter(2, exe.getDrugProject().getId())
						.setParameter(3, exe.getUseDrugDate()).setParameter(4, curTimeStart).setParameter(5, curTimeEnd)
						.getResultList();
				if (exes != null && exes.size() > 0) {
					exe.setErrcode(15);
					return exe;
				}
			} catch (ParseException e1) {
				logger.error(e1);
			}

			// 更改用药量
			CustomerDrug customerDrug = exe.getCustomerDrug();
			if (customerDrug.getDrugNum() - exe.getDrugNum() < 0) {
				exe.setErrcode(14);
				return exe;
			}
			customerDrug.setDrugNum(customerDrug.getDrugNum() - exe.getDrugNum());
			customerDrug.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(CustomerDrug.class);
			dslJpaService.update(customerDrug);
			// 创建用药计划执行
			if (exe.getExeDate() == null) {
				exe.setExeDate(CommonUtil.getCurrTimes());
			}
			dslJpaService.setEntityClass(CustomerDrugProjectExe.class);
			dslJpaService.create(exe);
			// 生成库存记录
			CustomerDrugRecord record = new CustomerDrugRecord();
			record.setCustomerDrug(customerDrug);
			record.setAddDrugNum(exe.getDrugNum());
			record.setAddType(commonService.getDicttype(CommonConstants.DICTTYPE.ADD_DRUG_TYPE_OUT.label()));
			record.setDrugNum(customerDrug.getDrugNum());
			if (exe.getLastUpdateUser() != null) {
				record.setGatherStaff(exe.getLastUpdateUser().getName());
			}
			record.setCreateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(CustomerDrugRecord.class);
			dslJpaService.create(record);
			// 判断是否发起药量不足提醒
			int msgFlag = 0;// checkDrugNum(customerDrug);
			if (msgFlag == 1) {
				// 关注此老人的
				List<User> users = this.em
						.createQuery(
								" select c.staff from StaffCustomer c where c.delStatus != ?1  and c.customer.id = ?2 ")
						.setParameter(1, (short) 1).setParameter(2, customerDrug.getCustomer().getId()).getResultList();
				if (users != null && users.size() > 0) {
					for (User user : users) {
						String openId = user.getOpenId();
						if (openId != null && !"".equals(openId)) {
							String templateID = properties.getProperty("weixin.drug_templateId");
							HashMap<String, String> tempData = new HashMap<String, String>();
							tempData.put("first", customerDrug.getDrug().getName());
							tempData.put("keyword1", customerDrug.getDrugNum().toString());// 剩余量
							tempData.put("keyword2", CommonUtil.getCurrTimeForString());// 时间
							// tempData.put("keyword3", "");
							tempData.put("remark", "用药人:" + customerDrug.getCustomer().getName());
							try {
								weiXinService.send_template_message(openId, tempData, "", templateID);
							} catch (Exception e) {
								logger.error("weixin send template msg error:" + e);
							}
						}
					} // end for user
				}
			} // end if msgFlag
		} else {
			dslJpaService.setEntityClass(CustomerDrugProjectExe.class);
			dslJpaService.update(exe);
		}
		return exe;
	}

	/**
	 * 验证剩余药量是否足够 drugNum 客户剩余药量
	 */
	public int checkDrugNum(CustomerDrug cd) {
		Double drugUsePlan = 0.0;// 计划未来10天用药量
		Double dayNum = Double.valueOf(properties.getProperty("drug.day_num"));
		StringBuilder queryNow = new StringBuilder(
				"select c from CustomerDrugProject c where c.delStatus!=1 and c.customerDrug.id=?1 ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, cd.getId()).getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else {
			drugUsePlan = ((CustomerDrugProject) dataList.get(0)).getUseDrugNum()
					* ((CustomerDrugProject) dataList.get(0)).getUseDrugFreq() * 10;
		}
		if (cd.getDrugNum() >= drugUsePlan) {
			return 0;// 充足
		} else {
			return 1;// 不足
		}
	}

	/**
	 * 获取老人对应的护理组Staff
	 */
	public List<Employee> getEmployeeByCID(long customerId) {
		StringBuilder queryEmployee = new StringBuilder(
				" select en.employee from EmployeeNursingGroup en where en.delStatus != 1 and en.group in "
						+ " ( select bn.group from BedNurseGroup bn where bn.delStatus != 1 and bn.bed in (select c.bed from Customer c where c.delStatus != 1 and c.id=?1) ) ");
		List<Employee> staffList = this.em.createQuery(queryEmployee.toString()).setParameter(1, customerId)
				.getResultList();
		return staffList;
	}

	/**
	 * 获取时间点之后的老人plandetail对应的projectitem
	 */
	public List<NursingProjectServiceItem> getProjectItemFromPlanDetail(long customerId, int dateTime) {
		Date now = new Date(dateTime * 1000l);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);
		StringBuilder query = new StringBuilder(
				"select distinct c.item from NursingPlanDetail c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2"
						+ " and ("
						+ "  ( c.yearTab>?3 ) or ( c.yearTab=?3 and c.weekIndex > ?4  ) or ( c.yearTab=?3 and c.weekIndex = ?4 and c.weekTab >?5 ) "
						+ " )");
		List<NursingProjectServiceItem> dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, customerId).setParameter(3, yearTab).setParameter(4, weekIndex)
				.setParameter(5, weekTab).getResultList();
		return dataList;
	}

	/**
	 * @author huibati 删除任务执行情况planexe同时删除相应增值服务账单 2017年7月19日
	 */
	@Transactional
	public void deleteNursingPlanExecute(NursingPlanExecute exe) {
		StringBuilder deleteExe = new StringBuilder(
				"update  NursingPlanExecute rp set rp.delStatus=1 where rp.id = ?1  ");
		this.em.createQuery(deleteExe.toString()).setParameter(1, exe.getId()).executeUpdate();
		StringBuilder deleteServiceBill = new StringBuilder(
				"update  CustomerServiceBill rp set rp.delStatus=1 where rp.exe.id = ?1 ");
		this.em.createQuery(deleteServiceBill.toString()).setParameter(1, exe.getId()).executeUpdate();
	}

	/**
	 * 获取老人每天需要的护理服务和用药计划总数
	 *
	 * @author ytche
	 * @param customerList
	 * @param positonType
	 * @param itemType
	 * @return
	 * @date 2017年8月23日 下午6:17:16
	 */
	public int getDayServiceNum(List<Customer> customerList) {
		// 生活照护类服务
		final String itemType = "serviceType2";

		List<Long> customerIdList = Lists.newArrayList();
		for (Customer customer : customerList) {
			customerIdList.add(customer.getId());
		}
		List<NursingPlanDetail> detailList = getPlanDetailByCustomer(customerIdList, null, itemType);
		Integer nursingPlanNum = detailList == null ? 0 : detailList.size();
		List<CustomerDrugProject> projectList = getDrugProjectByCustomer(customerIdList, null, itemType);
		Integer drugProjectNum = 0;
		for (CustomerDrugProject customerDrugProject : projectList) {
			String[] timeArray = customerDrugProject.getUseDrugDate().split(",");
			drugProjectNum += timeArray.length;
		}
		return nursingPlanNum + drugProjectNum;
	}

	/**
	 * 产生护理项目标签随机产生remark
	 * 
	 * @author huibati
	 * @param 2017年9月9日
	 */
	public ServiceFinishLevel createServiceFinishLevel(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				" select en from ServiceFinishLevel en where en.delStatus != 1 and en.item.id =?1 and en.remark = ?2 ");
		String code = "";
		while (true) {
			code = "c" + CommonUtil.buildRandom(8);
			List<ServiceFinishLevel> dataList = this.em.createQuery(query.toString())
					.setParameter(1, data.getItem().getId()).setParameter(2, code).getResultList();
			if (dataList == null || dataList.size() == 0) {
				data.setRemark(code);
				break;
			}
		}
		dslJpaService.setEntityClass(ServiceFinishLevel.class);
		dslJpaService.create(data);
		return data;
	}

	/**
	 * 产生用药以及护理计划执行记录
	 */
	public List<ServicesExe> getServicesExe(Integer startTime, Integer endTime, Long customerId) {
		StringBuilder queryLevel = new StringBuilder(
				"select  c  from ServiceFinishLevel c where delStatus=0 and (tenant.id= :tenantId or remark like 'default%' )");
		List<ServiceFinishLevel> levels = this.em.createQuery(queryLevel.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId()).getResultList();
		Map<String, String> levelMap = (Map<String, String>) levels.stream().collect(
				Collectors.toMap(ServiceFinishLevel::getRemark, ServiceFinishLevel::getName, (key1, key2) -> key2));

		long idTemp = 8;
		List<ServicesExe> dataList = new ArrayList<>();
		StringBuilder queryStr = new StringBuilder(
				"select  c,c3 from CustomerDrugProjectExe c, Conf c3 where c.delStatus=0 and c.tenant.id= :tenantId "
						+ " and c.createDateTime >= :startTime " 
						+ " and c.createDateTime <:endTime "
						+ " and c.customerDrug.customer.id = :customerId"
						+ " and c3.code='drugDay' "
						+ " order by c.createDateTime ");
		List drugProjectExes = this.em.createQuery(queryStr.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.setParameter("startTime", startTime).setParameter("endTime", endTime)
				.setParameter("customerId", customerId).getResultList();
		if (drugProjectExes != null) {
			Iterator it = drugProjectExes.iterator();
			while (it.hasNext()) {
				Object[] res = (Object[]) it.next();
				double useDrugNum=((CustomerDrugProjectExe)res[0]).getDrugProject().getUseDrugNum();
				double useDrugFreq=((CustomerDrugProjectExe)res[0]).getDrugProject().getUseDrugFreq();
				double drugNum=((CustomerDrugProjectExe)res[0]).getDrugProject().getCustomerDrug().getDrugNum();
				Conf fConf=((Conf)res[1]);
				double dayNum=Double.parseDouble(fConf.getValue());
				if (drugNum <= dayNum * useDrugFreq * useDrugNum) {
					int days=0;
					if(drugNum<=0){
						
					}else{
						days=(int) (drugNum/(useDrugFreq * useDrugNum));
					}
					((CustomerDrugProjectExe)res[0]).setRemarkAdd(days+"");
				}
				ServicesExe sexe = new ServicesExe();
				sexe.setDrugExe((CustomerDrugProjectExe)res[0]);
				sexe.setId(idTemp);
				dataList.add(sexe);
				idTemp++;
				} 
//			for (CustomerDrugProjectExe exe : drugProjectExes) {
//				ServicesExe sexe = new ServicesExe();
//				sexe.setDrugExe(exe);
//				sexe.setId(idTemp);
//				dataList.add(sexe);
//				idTemp++;
//			}
		}
		StringBuilder queryStrP = new StringBuilder(
				"select  c  from NursingPlanExecute c where delStatus=0 and tenant.id= :tenantId "
						+ " and createDateTime >= :startTime " 
						+ " and createDateTime <:endTime "
						+ " and itemProject.project.customer.id = :customerId " 
						+ " order by createDateTime ");
		List<NursingPlanExecute> planExes = this.em.createQuery(queryStrP.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.setParameter("startTime", startTime).setParameter("endTime", endTime)
				.setParameter("customerId", customerId).getResultList();
		if (planExes != null) {
			for (NursingPlanExecute exe : planExes) {
				if (exe.getExeTabRemark() != null && exe.getExeTabRemark().contains("remarkStr")) {
					String[] temp = exe.getExeTabRemark().replace(":", "").replace("remarkStr", "").replace("{", "").replace("}", "")
							.replace("\"", "").split(",");
					String jsonString = "";
					for (String code : temp) {
						jsonString += levelMap.get(code) + ",";
					}
					if(jsonString.length()>0){
						jsonString=jsonString.substring(0, jsonString.length()-1);
					}
					exe.setExeTabRemark(jsonString);
				}
				ServicesExe sexe = new ServicesExe();
				sexe.setItemExe(exe);
				sexe.setId(idTemp);
				dataList.add(sexe);
				idTemp++;
			}
		}
		return dataList;
	}
}
